package histogram;

import java.awt.image.BufferedImage;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Arrays;
import java.util.Locale;
import java.util.Scanner;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;

public class ReadHistRes {

    String resFile = "Neiro 6_20 50 10.txt";
    String originPath = "marked 6_20.bmp";
    int windSize = 40;
    int offset = 8;
    final int EDGE = 0;
    final int MITAH = 1;
    final int LIPID = 2;
    final int BACK = 3;
    int edgeMatr[][];
    int mitahMatr[][];
    int lipidMatr[][];
    int backMatr[][];
    int xMax = 0;
    int yMax = 0;
    int resultMatrix[][];
    int realMatrix[][];

    public ReadHistRes(BufferedImage image) {
        readResults(resFile);
        paintImage(image);
        loadImage(originPath);
        readReal();
        compareResults(image);
    }

    private void paintImage(BufferedImage image) {
        int mitColor[] = {255, 0, 0, 0};
        int lipidColor[] = {100, 255, 0, 0};
        int edgeColor[] = {0, 0, 0, 0};
        int backColor[] = {120, 90, 105, 0};

        System.out.println(image.getWidth() + "  " + image.getHeight());
        for (int i = 0; i < xMax; i++) {
            for (int j = 0; j < yMax; j++) {

                int max = edgeMatr[i][j];
                int index = EDGE;
                if (mitahMatr[i][j] > max) {
                    max = mitahMatr[i][j];
                    index = MITAH;
                }
                if (lipidMatr[i][j] > max) {
                    max = lipidMatr[i][j];
                    index = LIPID;
                }
                if (backMatr[i][j] > max) {
                    max = backMatr[i][j];
                    index = BACK;
                }

                WritableRaster raster = image.getRaster();
                int curColor[] = new int[4];
                raster.getPixel(i, j, curColor);
                switch (index) {
                    case EDGE:
                        for (int p = 0; p < 4; p++) {
                            curColor[p] = (curColor[p] + edgeColor[p]) / 2;
                        }
                        resultMatrix[i][j] = BACK;
                        break;
                    case MITAH:
                        for (int p = 0; p < 4; p++) {
                            curColor[p] = (curColor[p] + mitColor[p]) / 2;
                        }
                        resultMatrix[i][j] = LIPID;
                        break;
                    case LIPID:
                        for (int p = 0; p < 4; p++) {
                            curColor[p] = (curColor[p] + lipidColor[p]) / 2;
                        }
                        resultMatrix[i][j] = MITAH;
                        break;
                    case BACK:
                        for (int p = 0; p < 4; p++) {
                            curColor[p] = (curColor[p] + backColor[p]) / 2;
                        }
                        resultMatrix[i][j] = BACK;
                        break;
                }
                raster.setPixel(i, j, curColor);
            }
        }
        System.out.println("painted");
    }

    void readResults(String fileName) {
        try {

            Scanner scan = new Scanner(new File(resFile));
            scan.useLocale(Locale.UK);
            xMax = scan.nextInt() + windSize;
            yMax = scan.nextInt() + windSize;

            edgeMatr = new int[xMax][yMax];
            lipidMatr = new int[xMax][yMax];
            mitahMatr = new int[xMax][yMax];
            backMatr = new int[xMax][yMax];
            resultMatrix = new int[xMax][yMax];
            realMatrix = new int[xMax][yMax];

            init(xMax, yMax, edgeMatr);
            init(xMax, yMax, lipidMatr);
            init(xMax, yMax, mitahMatr);
            init(xMax, yMax, backMatr);
            init(xMax, yMax, resultMatrix);
            init(xMax, yMax, realMatrix);

            while (scan.hasNext()) {
                int x = scan.nextInt();
                int y = scan.nextInt();
                int realLabel = scan.nextInt();

//                double tmp = scan.nextDouble();
                int actualLabel = scan.nextInt();
//                int actualLabel = (int)tmp;

                switch (actualLabel) {
                    case 0:
                        mark(x, y, edgeMatr);
                        break;
                    case 1:
                        mark(x, y, mitahMatr);
                        break;
                    case 2:
                        mark(x, y, lipidMatr);
                        break;
                    case 3:
                        mark(x, y, backMatr);
                        break;
                }
            }
            System.out.println("readed");
        } catch (FileNotFoundException ex) {
            Logger.getLogger(ReadHistRes.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    private void init(int xMax, int yMax, int mas[][]) {
        for (int i = 0; i < xMax; i++) {
            for (int j = 0; j < yMax; j++) {
                mas[i][j] = 0;
            }
        }
    }

    private void mark(int x, int y, int mas[][]) {
        for (int i = x; i < x + windSize; i++) {
            for (int j = y; j < y + windSize; j++) {
                mas[i][j]++;
            }
        }
    }
    BufferedImage rootMarked = null;

    void loadImage(String marked) {
        try {
            rootMarked = ImageIO.read(new File(marked));
        } catch (IOException ex) {
            System.out.println(ex.getMessage());
        }
    }

    private void readReal() {
        int mitColor[] = {0, 255, 255, 0};
        int lipidColor[] = {255, 175, 175, 0};

        int m = 0;
        int l = 0;
        int b = 0;
        for (int i = 0; i < xMax; i++) {
            for (int j = 0; j < yMax; j++) {

                Raster colorMarked = rootMarked.getRaster();
                int sampleMar[] = new int[4];
                colorMarked.getPixel(i, j, sampleMar);

                if (Arrays.equals(sampleMar, mitColor)) {
                    m++;
                    realMatrix[i][j] = MITAH;
                } else if (Arrays.equals(sampleMar, lipidColor)) {
                    l++;
                    realMatrix[i][j] = LIPID;
                } else {
                    b++;
                    realMatrix[i][j] = BACK;
                }
            }
        }
        System.out.println(m + " " + l + " " + b);
    }

    void compareResults(BufferedImage image) {
        int square = xMax * yMax;
        int coinside = 0;
        int coinColor[] = {0, 0, 255, 0};
        WritableRaster raster = image.getRaster();
        for (int i = 0; i < xMax; i++) {
            for (int j = 0; j < yMax; j++) {
                if (realMatrix[i][j] == resultMatrix[i][j]) {
                    coinside++;
                    raster.setPixel(i, j, coinColor);
                }
            }
        }
        double percent = coinside * 100.0 / square;
        System.out.println(xMax + "  " + yMax + " " + square);
        System.out.println(coinside);
        System.out.println("Coinside: " + percent);
    }
}
